package com.ycrlkj.android.modulescore.main.activity.app;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import android.Manifest;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.navi.NaviSetting;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.blankj.utilcode.util.ToastUtils;
import com.lxj.xpopup.impl.LoadingPopupView;
import com.ycrlkj.android.modulesbase.libbase.utils.Logger;
import com.ycrlkj.android.modulescore.main.databinding.ActivityLocationBinding;
import com.ycrlkj.android.modulescore.main.viewmodel.GaodeLocationViewModel;
import com.ycrlkj.android.modulespublic.common.constant.RoutePath;
import com.ycrlkj.android.modulespublic.common.map.amap.GaodeLocation;
import com.ycrlkj.android.modulespublic.common.utils.xpopup.XPopupUtil;
import com.ycrlkj.android.modulespublic.common.widget.titlebar.MTitleBar;

import java.io.Serializable;
import java.util.List;

import dagger.hilt.android.AndroidEntryPoint;
import lombok.SneakyThrows;
import pub.devrel.easypermissions.EasyPermissions;

@AndroidEntryPoint
@Route(path = RoutePath.PAGE_LOCATION)
public class LocationActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {

    private ActivityLocationBinding binding;
    private GaodeLocationViewModel viewModel;
    private LoadingPopupView loadingPopupView;

    @Autowired
    String title;

    @Autowired
    int type;

    @Autowired
    GaodeLocation gaodeLocation;//ARouter .withSerializable("mLocation", startMLocation) 携带进来的序列化参数, 此处可以直接用javaBean接收, 会自动反序列化

    private final Intent intent = new Intent();

    private MapView mapView;
    private AMap aMap;

    //声明AMapLocationClient类对象
    private AMapLocationClient aMapLocationClient;
    //声明定位回调监听器
    private AMapLocationListener aMapLocationListener;

    //地理编码
    private GeocodeSearch geocodeSearch;

    private AnimatorSet animatorSet;

    private UiSettings uiSettings;//定义一个UiSettings对象

    public void animTranslate() {
        View mapCenterPoint = binding.mapCenterPoint;
        if (animatorSet == null) {
            animatorSet = new AnimatorSet();
            animatorSet.playTogether(ObjectAnimator.ofFloat(mapCenterPoint, "scaleX", 1, 0.5f, 1).setDuration(300)
                    , ObjectAnimator.ofFloat(mapCenterPoint, "scaleY", 1, 0.5f, 1).setDuration(300));
        }
        animatorSet.start();
    }

    @SneakyThrows
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ARouter.getInstance().inject(this);
        binding = ActivityLocationBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        viewModel = new ViewModelProvider(this).get(GaodeLocationViewModel.class);
        binding.setViewModel(viewModel);
        binding.setLifecycleOwner(this);

        viewModel.getGaodeLocation().setValue(gaodeLocation);
        viewModel.type.setValue(type);

        initPermissions();
        initTitleBar();
        initMap(savedInstanceState);
    }

    public void initMap(Bundle savedInstanceState) throws AMapException {

        NaviSetting.updatePrivacyShow(this, true, true);
        NaviSetting.updatePrivacyAgree(this, true);

        mapView = binding.map;
        mapView.onCreate(savedInstanceState);

        aMap = mapView.getMap();

        uiSettings = aMap.getUiSettings();//实例化UiSettings类对象

        //uiSettings.setAllGesturesEnabled(false);//所有手势
        uiSettings.setZoomGesturesEnabled(true);//缩放手势
        uiSettings.setScrollGesturesEnabled(true);//滑动手势
        uiSettings.setRotateGesturesEnabled(false);//旋转手势
        uiSettings.setTiltGesturesEnabled(false);//倾斜手势

        //地图移动监听
        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {
                //此方法移动每一个像素触发一次
            }

            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {
                animTranslate();
                //逆地理编码查询
                getGeocodeSearch(cameraPosition.target);

                //设备定位图标动画
                setTranslateAnimation(binding.locationIcon);
                setTranslateAnimation(binding.locationInfo);

                gaodeLocation = new GaodeLocation();

                gaodeLocation.setLatitude(cameraPosition.target.latitude);
                gaodeLocation.setLongitude(cameraPosition.target.longitude);
            }
        });

        //设置地理编码查询
        geocodeSearch = new GeocodeSearch(this);
        geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int errorCode) {
                if (errorCode == AMapException.CODE_AMAP_SUCCESS) {

                    RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();

                    if (regeocodeAddress != null) {
                        String formatAddress = regeocodeAddress.getFormatAddress();

                        String province = regeocodeAddress.getProvince();
                        String city = regeocodeAddress.getCity();
                        String district = regeocodeAddress.getDistrict();

                        gaodeLocation.setAddress(formatAddress);
                        gaodeLocation.setProvince(province);
                        gaodeLocation.setCity(city);
                        gaodeLocation.setDistrict(district);

                        viewModel.getGaodeLocation().setValue(gaodeLocation);
                    }
                } else {
                    ToastUtils.showLong("获取当前位置信息失败");
                }
            }

            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int errorCode) {
                //此方法用不到
                //Logger.e("onGeocodeSearched: geocodeResult = " + geocodeResult + ", errorCode = " + errorCode);
            }
        });


        try {

            AMapLocationClient aMapLocationClient = new AMapLocationClient(getApplicationContext());


            aMapLocationClient.setLocationListener(aMapLocationListener);

            AMapLocationClientOption option = new AMapLocationClientOption();
            //设置定位模式为高精度模式，Battery_Saving为低功耗模式，Device_Sensors是仅设备模式
            option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位场景，目前支持三种场景（签到、出行、运动，默认无场景）
            option.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.SignIn);
            //获取一次定位结果, 默认为false
            option.setOnceLocation(true);
            //是否返回地址信息（默认true）
            option.setNeedAddress(true);
            //设置定位间隔,单位毫秒,默认为2000ms
            //option.setInterval(2000);

            //给定位客户端对象设置定位参数
            aMapLocationClient.setLocationOption(option);
            //设置场景模式后最好调用一次stop，再调用start以保证场景模式生效
            aMapLocationClient.stopLocation();

            //启动定位
            aMapLocationClient.startLocation();

            if (gaodeLocation.getLatitude() == 0) {
                //Logger.e("没有携带定位信息, 开始定位");
                loadingPopupView = XPopupUtil.showLoading(this, "正在获取定位信息");
                XPopupUtil.hideLoadingDelay(loadingPopupView);

                //启动定位
                aMapLocationClient.startLocation();
            } else {
                //Logger.e("携带定位信息");

                //移动相机到地图中心
                LatLng latLng = new LatLng(gaodeLocation.getLatitude(), gaodeLocation.getLongitude());
                moveCamera(latLng);
            }
        }catch(Exception e){
            ToastUtils.showLong("定位失败");
            e.printStackTrace();
        }

    }

    //逆地理编码获取当前位置信息
    private void getGeocodeSearch(LatLng latlng) {
        //第二参数表示范围多少米(在获取poi列表时有用), 第三个参数表示是火系坐标系还是GPS原生坐标系
        RegeocodeQuery query = new RegeocodeQuery(new LatLonPoint(latlng.latitude, latlng.longitude), 1000, GeocodeSearch.AMAP);
        geocodeSearch.getFromLocationAsyn(query);
    }

    public void initAMapLocationListener() {
        aMapLocationListener = new AMapLocationListener() {
            @Override
            public void onLocationChanged(AMapLocation aMapLocation) {

                Logger.e("initAMapLocationListener: aMapLocation = " + aMapLocation);
                //aMapLocation 属性如下
//                latitude = 30.669067
//                longitude = 111.393557
//                province = 湖北省
//                coordType = GCJ02
//                city = 宜昌市
//                district = 伍家岗区
//                cityCode = 0717
//                adCode = 420503
//                address = 湖北省宜昌市伍家岗区东山三路549号靠近城东U谷A区
//                country = 中国
//                road = 东山三路
//                poiName = 城东U谷A区
//                street = 东山三路
//                streetNum = 549 号
//                aoiName = 城东U谷
//                poiid =
//                floor =
//                errorCode = 0
//                errorInfo = success
//                locationDetail = id:SamplaXFnbmlrZmRkY2s4bm45bWJnZGQ5MDJkYmZlLA == csid:87f 1e321505d 4d 0482 a890c1eed7139e
//                description = 在城东U谷A区附近
//                locationType = 5
//                conScenario = -10


                if (aMapLocation == null) {
                    Logger.e("获取定位失败");
                    ToastUtils.showLong("获取定位失败");
                    return;
                }

                if (aMapLocation.getErrorCode() != 0) {
                    Logger.e("获取定位失败, " + aMapLocation.getErrorInfo());
                    ToastUtils.showLong("获取定位失败, " + aMapLocation.getErrorInfo());
                    return;
                }

                int locationType = aMapLocation.getLocationType();//获取当前定位结果来源，如网络定位结果，详见定位类型表
                double latitude = aMapLocation.getLatitude();//获取纬度
                double longitude = aMapLocation.getLongitude();//获取经度
                float accuracy = aMapLocation.getAccuracy();//获取精度信息
                String address = aMapLocation.getAddress();//地址，如果option中设置isNeedAddress为false，则没有此结果，网络定位结果中会有地址信息，GPS定位不返回地址信息。
                String country = aMapLocation.getCountry();//国家信息
                String province = aMapLocation.getProvince();//省信息
                String city = aMapLocation.getCity();//城市信息
                String district = aMapLocation.getDistrict();//城区信息
                String street = aMapLocation.getStreet();//街道信息
                String streetNum = aMapLocation.getStreetNum();//街道门牌号信息
                String cityCode = aMapLocation.getCityCode();//城市编码
                String adCode = aMapLocation.getAdCode();//地区编码
                String poiName = aMapLocation.getPoiName();//获取当前定位点的POI信息
                String buildingId = aMapLocation.getBuildingId();//获取当前室内定位的建筑物Id
                String floor = aMapLocation.getFloor();//获取当前室内定位的楼层
                int gpsAccuracyStatus = aMapLocation.getGpsAccuracyStatus();//获取GPS的当前状态
                long time = aMapLocation.getTime();//获取定位时间

                gaodeLocation.setLocationType(locationType);
                gaodeLocation.setLatitude(latitude);
                gaodeLocation.setLongitude(longitude);
                gaodeLocation.setAccuracy(accuracy);
                gaodeLocation.setAddress(address);
                gaodeLocation.setCountry(country);
                gaodeLocation.setProvince(province);
                gaodeLocation.setCity(city);
                gaodeLocation.setDistrict(district);
                gaodeLocation.setStreet(street);
                gaodeLocation.setStreetNum(streetNum);
                gaodeLocation.setCityCode(cityCode);
                gaodeLocation.setAdCode(adCode);
                gaodeLocation.setPoiName(poiName);
                gaodeLocation.setBuildingId(buildingId);
                gaodeLocation.setFloor(floor);
                gaodeLocation.setGpsAccuracyStatus(gpsAccuracyStatus);
                gaodeLocation.setTime(time);

                LatLng latLng = new LatLng(latitude, longitude);

                //移动相机到定位中心
                moveCamera(latLng);

                XPopupUtil.hideLoading(loadingPopupView);
            }
        };
    }


    public void moveCamera(LatLng position) {
        CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(
                position, //中心点坐标，地图目标经纬度
                17,  //目标缩放级别
                0, //目标倾斜角[0.0 ~ 45.0] (垂直地图时为0)
                0)); //目标旋转角 0~360° (正北方为0)
        aMap.moveCamera(cameraUpdate); //移动地图
    }

    //组件上下跳动动画
    private void setTranslateAnimation(View view) {
        ValueAnimator animator = ValueAnimator.ofInt(0, -80, 0);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int currentValue = (Integer) animation.getAnimatedValue();
                view.setTranslationY(currentValue);
                //刷新视图
                view.requestLayout();
            }
        });
        //animator.setRepeatMode(ValueAnimator.RESTART); //动画重复模式
        //animator.setRepeatCount(ValueAnimator.INFINITE); //动画重复次数
        //animator.setInterpolator(new AccelerateDecelerateInterpolator());
        //animator.setDuration(1000); //动画持续时间
        animator.start();
    }

    public void handleCancel(View view) {
        intent.putExtra("gaodeLocation", (Serializable) gaodeLocation);
        setResult(400, intent);//点击了取消, 返回 400
        finish();
    }

    public void handleConfirm(View view) {
        intent.putExtra("gaodeLocation", (Serializable) gaodeLocation);
        setResult(200, intent);//点击了确定, 返回 200
        finish();
    }


    public void handleOpenCollect(View view) {
        ToastUtils.showLong("还未实现地址薄功能");
    }

    public void handleAddCollect(View view) {
        ToastUtils.showLong("已收藏到地址薄");
    }


    public void initTitleBar() {
        MTitleBar titleBar = binding.mTitleBar;
        titleBar.setTitle(title);
        titleBar.setBtnEvents(new MTitleBar.BtnEvents() {
            @Override
            public void setBtnLeftOnClickListener() {
                LocationActivity.this.finish();
            }

            @Override
            public void setBtnRightOnClickListener() {
            }
        });

    }

    /* #region ========================= 权限管理 开始 ====================== */
    public void initPermissions() {
        //定位需要申请的权限
        String[] perms = {
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.READ_PHONE_STATE
        };

        if (EasyPermissions.hasPermissions(this, perms)) {//检查是否获取该权限
            Logger.e("已获取定位权限");
        } else {
            EasyPermissions.requestPermissions(this, "必要的权限", 0, perms);
        }
    }

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
        Logger.e("定位请求成功");
    }

    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        Logger.e("定位请求失败");
    }
    /* #endregion ====================== 权限管理 结束 ====================== */



    /** 必须重写以下方法 */
    @Override
    protected void onResume() {
        super.onResume();
        //重新绘制加载地图
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //暂停地图的绘制
        mapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //销毁地图
        mapView.onDestroy();
    }

}